package com.fm.base.database;

import java.util.Arrays;
import java.util.Collection;

public class DBDataFilter {
    public static DBDataFilter equal(String subject, Object object) {
        return new DBDataFilter(Operator.equal, subject, object);
    }

    public static DBDataFilter notEqual(String subject, Object object) {
        return new DBDataFilter(Operator.notEqual, subject, object);
    }

    public static DBDataFilter lessThan(String subject, Object object) {
        return new DBDataFilter(Operator.lt, subject, object);
    }

    public static DBDataFilter greaterThan(String subject, Object object) {
        return new DBDataFilter(Operator.gt, subject, object);
    }

    public static DBDataFilter exist(String subject) {
        return new DBDataFilter(Operator.exist, subject);
    }

    public static DBDataFilter and(DBDataFilter... filters) {
        return new DBDataFilter(Operator.and, filters);
    }

    public static DBDataFilter or(DBDataFilter... filters) {
        return new DBDataFilter(Operator.or, filters);
    }

    public static DBDataFilter in(String subject, Object... values) {
        Object[] vals = new Object[2];
        vals[0] = subject;
        vals[1] = Arrays.asList(values);
        return new DBDataFilter(Operator.in, vals);
    }

    public static DBDataFilter in(String subject, Collection<?> values) {
        Object[] vals = new Object[2];
        vals[0] = subject;
        vals[1] = values;
        return new DBDataFilter(Operator.in, vals);
    }

    private Operator operator;
    private Object[] values;

    private DBDataFilter(Operator operator, Object... values) {
        switch (operator) {
            case equal:
            case notEqual:
            case lt:
            case gt:
            case exist:
                break;
            case in:
                if (values[0] instanceof DBDataFilter) {
                    throw new IllegalArgumentException("first value mustn't be " + values[0].getClass());
                }
                break;
            case and:
            case or:
                for (Object o : values) {
                    if (!(o instanceof DBDataFilter)) {
                        throw new IllegalArgumentException("value must be DBDataFilter");
                    }
                }
                break;
            default:
                throw new RuntimeException("not support");
        }
        this.operator = operator;
        this.values = values;
    }

    public Operator getOperator() {
        return operator;
    }

    public Object[] getValues() {
        return values;
    }
}